#ifndef COROUTINE_FD_MANAGER_H
#define COROUTINE_FD_MANAGER_H

#include "../base/Singleton.hpp"

#include <cstdint>
#include <memory>
#include <shared_mutex>
#include <unordered_map>
namespace DBServer {
namespace coroutine {

class FdContext : public std::enable_shared_from_this<FdContext> {
public:
    using ptr = std::shared_ptr<FdContext>;

    FdContext(int fd);

    ~FdContext();

    /// @brief fd是否为socket
    bool attr_socket() { return is_socket; }

    /// @brief fd是否已经关闭
    bool attr_close() { return is_closed; }

    /// @brief fd是否被设置为hook非阻塞模式 
    bool attr_sys_nonblock() { return sys_nonblock; }

    /// @brief fd是否被设置为用户非阻塞模式
    bool attr_user_nonblock() { return user_nonblock; }

    /// @brief fd context是否已经被初始化了
    bool attr_init() { return is_init; }

    void set_user_nonblock(bool v) { user_nonblock = v; }

    void set_sys_nonblock(bool v) { sys_nonblock = v; }

    void set_timeout(int type, std::uint64_t v);

    std::uint64_t get_timeout(int type);

private:
    bool init();

private:
    bool is_init : 1;
    bool is_socket : 1;             // 是否socket
    bool sys_nonblock : 1;          // 是否被hook为非阻塞
    bool user_nonblock : 1;         // 是否被用户主动设置为非阻塞(通过调用fcntl)
    bool is_closed : 1;             // 是否关闭
    int fd;
    std::uint64_t recv_timeout;     
    std::uint64_t send_timeout;
};

class FdManager : public DBServer::Base::Singleton<FdManager> {
public:
    FdManager() = default;
    ~FdManager() = default;

    FdContext::ptr get(int fd);

    void reg(int fd_ctx);

    void del(int fd);

private:    
    std::shared_mutex mtx;
    std::unordered_map<int, FdContext::ptr> datas;

};

}   // coroutine   
}   // DBServer

#endif // !COROUTINE_FD_MANAGER_H